package com.ysy.leader;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @program: zookeeper-demo
 * @description: leader选择demo2
 * @author: yeshiyuan
 * @create: 2019-06-18 10:13
 **/
public class LeaderChooseDemo2 implements Watcher{

    private ZooKeeper zk = null;
    private String root;

    private static int sessionTimeout = 30000;


    public LeaderChooseDemo2(String connectString, String root) {
        this.root = root;
        try {
            zk = new ZooKeeper(connectString, sessionTimeout, this);
            Stat s = zk.exists(root, false);
            if (s == null) {
                zk.create(root, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    void findLeader() throws InterruptedException, UnknownHostException, KeeperException {
        byte[] leader = null;
        try {
            leader = zk.getData(root + "/leader", true, null);
        } catch (KeeperException e) {
            if (e instanceof KeeperException.NoNodeException) {
                System.out.println("领导者节点不存在");
            } else {
                throw e;
            }
        }
        if (leader != null) {
            following();
        } else {
            String newLeader = null;
            byte[] localhost = InetAddress.getLocalHost().getAddress();
            try {
                newLeader = zk.create(root + "/leader", localhost, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            } catch (KeeperException e) {
                if (e instanceof KeeperException.NodeExistsException) {
                    e.printStackTrace();
                } else {
                    throw e;
                }
            }
            if (newLeader != null) {
                leading();
            } else {
                //mutex.wait();
            }
        }
    }

    public void process(WatchedEvent event) {
        if (event.getPath().equals(root + "/leader") && event.getType() == Event.EventType.NodeCreated) {
            System.out.println("得到通知");
            following();
        }
    }

    void leading() {
        System.out.println("成为领导者");
    }

    void following() {
        System.out.println("成为组成员");
    }

    public static void main(String[] args) {
        String connectString = "192.168.5.35:2181";

        LeaderChooseDemo2 le = new LeaderChooseDemo2(connectString, "/GroupMembers");
        try {
            le.findLeader();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
